/**
 *  \file can.c
 *
 *  \brief
 *
 *  \author Michael J. Hohmann  <michael.hohmann@linde-mh.de>
 *
 *
 */

/*===============================================[ private includes  ]================================================*/
#include <xmc4500/can_drv.h>
#include <xmc4500/can_hw.h>
#include "tar.h"
//---------------------
// Library Header  
#include "can.h"
#include "../assertor/assertor.h"
#include "../pal/pal_mem.h"

/*===============================================[ private defines   ]================================================*/
#define CAN_EXT_TABLE_SIZE 32
#define CAN_INT_TABLE_SIZE 32
/*===============================================[ private datatypes ]================================================*/


/** Private variables */
struct can_private
{
   struct candispatcher_obj dispatcher[can_channle_max];
   struct candispatcher_entry ext_table[ CAN_EXT_TABLE_SIZE ];
   struct candispatcher_entry int_table[ CAN_INT_TABLE_SIZE ];
};

/*===============================================[ private variables ]================================================*/
static struct can_private can;


/*===============================================[ private functions ]================================================*/

/*===============================================[ inline functions  ]================================================*/

/*===============================================[ public functions  ]================================================*/
RC can_initialize( void )
{
   pal_memzero( &can, sizeof can);
   candispatcher_construct(&can.dispatcher[can_channel_ext], can.ext_table, CAN_EXT_TABLE_SIZE ); // initialize dispatcher for can ext
   candispatcher_enable(&can.dispatcher[can_channel_ext], 1);

   candispatcher_construct(&can.dispatcher[can_channel_int], can.int_table, CAN_INT_TABLE_SIZE ); // initialize dispatcher for can int
   candispatcher_enable(&can.dispatcher[can_channel_int], 1);

   return RC_SUCCESS;
}


/* Send can message on the bus.
 *
 *
 *
 *  \param channel will not be used in MMU project
 *
 */
void can_install_rx_callback( enum can_channel channel, canmsg_id_t id, can_callback_function_t callback, void* data )
{
   candispatcher_install_callback( &can.dispatcher[channel], id, callback, data );
   mailbox_vInit(channel, id);
}

/* Send can message on the bus.
 *
 *
 *  \param msg pointer to the message
 *  \param channel will not be used in MMU project
 *
 */
void can_tx_msg(enum can_channel channel, struct canmsg *msg)
{
	msg->port = channel;
	send_can_message(msg);
}

void can_tx( enum can_channel channel, U32 id, void const* data, U8 len )
{
	struct canmsg msg;
	pal_memcpy(canmsg_set(&msg,id,len),data,len);
	can_tx_msg(channel, &msg );
}


/* this function is contained in the interface
 * it is for you to receive a can message from an interrupt
 *
 */
void can_process_message(struct canmsg *msg)
{
	candispatcher_dispatch_message( &can.dispatcher[msg->port], msg);
}

/*===============================================[ private functions ]================================================*/








/***********************************************************************************************************************
 *                             Copyright 2018 Linde Material Handling. All rights reserved.                             *
 ***********************************************************************************************************************/
